package sg.edu.nus.iss.billing.gui;

/**
 * @author sammil
 *
 */
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.MessageFormat;

import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.Size2DSyntax;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileFilter;

import sg.edu.nus.iss.billing.entity.Customer;
import sg.edu.nus.iss.billing.localization.MessageKeyManager;

public class GeneratedBillFrame extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7946441105406508237L;

	public static final int WIDTH = 1000;
	public static final int HEIGHT = 650;
	public static final int WIDTH_MARGIN = 10;
	public static final int HEIGHT_MARGIN = 10;
	JEditorPane editorPane = null;
	private String htmlString = "";
	static private PrintRequestAttributeSet attr;
	Customer customer = null;

	public void autoResize() {
		this.pack();
		// this.setSize(this.getWidth() + WIDTH_MARGIN, this.getHeight() +
		// HEIGHT_MARGIN);
		this.setLocationRelativeTo(null);
	}

	public GeneratedBillFrame(String title, Customer customer, String htmlString) {
		super(title);
		this.customer = customer;
		this.htmlString = htmlString;
		// setResizable(false);
		SessionContext.setUser(null);
		getContentPane().setLayout(new BorderLayout());
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent we) {
				dispose();
				
			}
		});
		init();
		autoResize();
		setVisible(true);
		
	}

	private void init() {
		getContentPane().add(createEditorPanel(), BorderLayout.CENTER);
		getContentPane().add(createActionButtonsPanel(), BorderLayout.SOUTH);
		getContentPane().validate();
	}

	public JPanel createEditorPanel() {

		JPanel editorPanel = new JPanel();
		editorPanel.setLayout(new BorderLayout());
		if (htmlString == null) {
			editorPane = new JEditorPane();
			editorPane.setContentType("text/html");
			editorPane.setText("<HTML><BODY>NO BILL AVAILABLE</BODY></HTML>");
			
			

			
		} else {
			
			editorPane = new JEditorPane();
			editorPane.setContentType("text/html");
			
			
			
			editorPane.setText(htmlString);
		}
		editorPane.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		editorPane.setEditable(false);
		JScrollPane scrollPane = new JScrollPane(editorPane);
		editorPanel.add(scrollPane, BorderLayout.CENTER);
		return editorPanel;
	}

	public JPanel createActionButtonsPanel() {
		JPanel p = new JPanel(new FlowLayout());
		JButton btnPrintButton = new JButton(MessageKeyManager
				.getMessage("bill.button.print"));
		JButton btnSaveButton = new JButton(MessageKeyManager
				.getMessage("bill.button.save"));
		JButton btnCancelButton = new JButton(MessageKeyManager
				.getMessage("bill.button.cancel"));

		btnPrintButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				MessageFormat footer = new MessageFormat("Page - {0}"); 
				print(editorPane.getPrintable(null, footer), new Insets(10, 10,
						10, 10));

			}
		});

		btnSaveButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				saveButtonPressed();
			}
		});

		btnCancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				cancelButtonPressed();
			}
		});

		p.add(btnPrintButton);
		p.add(btnSaveButton);
		p.add(btnCancelButton);
		return p;
	}

	void saveButtonPressed() {
		String workindDir = System.getProperty("user.dir");
		JFileChooser fileChooser = new JFileChooser(workindDir);
		FileFilter filter = new ExtensionFileFilter("HTM and HTML",
				new String[] { "HTM", "HTML" });
		fileChooser.setFileFilter(filter);

		if (customer != null) {
			File f = null;
			try {
				f = new File(new File(customer.getAccountNumber() + ".html")
						.getCanonicalPath());
			} catch (IOException e) {
			}
			fileChooser.setSelectedFile(f);
		}

		int rVal = fileChooser.showSaveDialog(GeneratedBillFrame.this);
		if (rVal == JFileChooser.APPROVE_OPTION) {
			String selectedFileName = fileChooser.getSelectedFile().getName();
			String selectedDirName = fileChooser.getCurrentDirectory()
					.toString();
			if (selectedFileName.toUpperCase().indexOf(".HTM") == -1) {
				selectedFileName += ".html";
			}
			saveFile(selectedDirName, selectedFileName);
		}
		if (rVal == JFileChooser.CANCEL_OPTION) {
			// DO NOTHING
		}
	}

	void cancelButtonPressed() {
		this.dispose();
	}

	private void saveFile(String dir, String fileName) {
		String saveFileContent = editorPane.getText();
		File destFileName = new File(dir + fileName);
		FileWriter fstream = null;
		BufferedWriter out = null;
		try {
			fstream = new FileWriter(destFileName);
			out = new BufferedWriter(fstream);
			out.write(saveFileContent);
			out.close();
			fstream.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	static public void print(final Printable printable, final Insets insets) {
		PrinterJob pjob = PrinterJob.getPrinterJob();
		pjob.setPrintable(printable);
		if (attr == null) {
			attr = new HashPrintRequestAttributeSet();
			float leftMargin = insets.left;
			float rightMargin = insets.right;
			float topMargin = insets.top;
			float bottomMargin = insets.bottom;
			attr.add(OrientationRequested.PORTRAIT);
			attr.add(MediaSizeName.ISO_A4);
			MediaSize mediaSize = MediaSize.ISO.A4;
			float mediaWidth = mediaSize.getX(Size2DSyntax.MM);
			float mediaHeight = mediaSize.getY(Size2DSyntax.MM);
			attr.add(new MediaPrintableArea(leftMargin, topMargin, (mediaWidth
					- leftMargin - rightMargin),
					(mediaHeight - topMargin - bottomMargin), Size2DSyntax.MM));

		}
		if (pjob.printDialog(attr)) {
			try {
				pjob.print(attr);
			} catch (PrinterException ex) {
				ex.printStackTrace();
			}
		}
	}

	public static void main(String[] argv) {
		String htmlString = "<HTML>  <BODY>   HELLO WORLD  </BODY> </HTML>";
		GeneratedBillFrame myExample = new GeneratedBillFrame("Generated Bill",
				null, htmlString);
	}

};

class ExtensionFileFilter extends FileFilter {
	String description;
	String extensions[];

	public ExtensionFileFilter(String description, String extension) {
		this(description, new String[] { extension });
	}

	public ExtensionFileFilter(String description, String extensions[]) {
		if (description == null) {
			this.description = extensions[0];
		} else {
			this.description = description;
		}
		this.extensions = (String[]) extensions.clone();
		toLower(this.extensions);
	}

	private void toLower(String array[]) {
		for (int i = 0, n = array.length; i < n; i++) {
			array[i] = array[i].toLowerCase();
		}
	}

	public String getDescription() {
		return description;
	}

	public boolean accept(File file) {
		if (file.isDirectory()) {
			return true;
		} else {
			String path = file.getAbsolutePath().toLowerCase();
			for (int i = 0, n = extensions.length; i < n; i++) {
				String extension = extensions[i];
				if ((path.endsWith(extension) && (path.charAt(path.length()
						- extension.length() - 1)) == '.')) {
					return true;
				}
			}
		}
		return false;
	}
}
